
#include <linux/fb.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/fcntl.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <unistd.h>

#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>

extern void render_gradient_soft(uint8_t* pixel, int w, int h, int pitch);
extern void render_project_depth_soft(uint8_t* pixel, int w, int h, int pitch);

#include <time.h>
uint64_t now_ms(void)
{
    struct timespec tspec;
    clock_gettime(CLOCK_MONOTONIC, &tspec);

    return tspec.tv_sec * 1000 + tspec.tv_nsec / 1000000;
}

int main(int argc, char *argv[])
{
    int fb_fd;
	struct fb_fix_screeninfo fb_fix;
	struct fb_var_screeninfo fb_var;

    int bytes_per_pix;
    size_t bytes_per_line;
    uint8_t *frame_buffer;

    int img_width = 640;
    int img_height = 480;

    uint8_t *image_frame;
    int img_x, img_y;
    
    fb_fd = open("/dev/fb0", O_RDWR);
    ioctl(fb_fd, FBIOGET_FSCREENINFO, &fb_fix);
    ioctl(fb_fd, FBIOGET_VSCREENINFO, &fb_var);
    
    printf("fb, fix: {smem: %u@%lu, type: %u, visual: %u, line_length: %u}\n"
        "fb, var: {res: %ux%u, offset: %ux%u, bits_per_pixel: %u}\n", 
        fb_fix.smem_len, fb_fix.smem_start, fb_fix.type, fb_fix.visual, fb_fix.line_length,
        fb_var.xres, fb_var.yres, fb_var.xoffset, fb_var.yoffset, fb_var.bits_per_pixel);

    bytes_per_pix = fb_var.bits_per_pixel / 8;
    //bytes_per_line = bytes_per_pix * fb_var.xres;
    bytes_per_line = fb_fix.line_length;

    frame_buffer = (uint8_t*)mmap((void*)fb_fix.smem_start, fb_fix.smem_len, (PROT_READ | PROT_WRITE), MAP_SHARED, fb_fd, 0);

    img_x = (fb_var.xres - img_width) / 2;
    img_y = (fb_var.yres - img_height) / 2;

    image_frame = frame_buffer + img_y * bytes_per_line + img_x * bytes_per_pix;

    render_gradient_soft(image_frame, img_width, img_height, bytes_per_line);
    ioctl(fb_fd, FBIOPAN_DISPLAY, 0);
    getchar();

    render_project_depth_soft(image_frame, img_width, img_height, bytes_per_line);
    ioctl(fb_fd, FBIOPAN_DISPLAY, 0);
    getchar();

    munmap(frame_buffer, fb_fix.smem_len);
    close(fb_fd);
    
    return 0;
}
